package entity

import (
	"context"
	"encoding/json"
	"github.com/spf13/cast"
	"nearby/biz/config"
	"nearby/biz/dal/db/po"
	"nearby/biz/dal/db/repo"
	"nearby/biz/model/vo"
	"nearby/biz/util"
	"time"
)

type PostContent struct {
	Text      string   `json:"text,omitempty"`       // 文本
	ImageUrls []string `json:"image_urls,omitempty"` // 图片链接列表
}

type Moment struct {
	ID           int64       `json:"id"`
	MomentID     int64       `json:"moment_id"`
	User         User        `json:"user"`          // 用户实体
	Content      PostContent `json:"content"`       // 动态内容
	ViewCount    int64       `json:"view_count"`    // 浏览量
	CommentCount int64       `json:"comment_count"` // 评论数
	LikeCount    int64       `json:"like_count"`    // 点赞数
	CreateAt     time.Time   `json:"create_at"`     // 创建时间
	ILikeIt      bool        `json:"i_like_it"`     // 当前登陆用户是否点赞
}

type GetMomentEntityRequest struct {
	MomentID int64 `json:"moment_id"`
}

func GetMomentEntity(ctx context.Context, req GetMomentEntityRequest) (*Moment, error) {
	momentRepo := repo.NewMomentRepo(ctx)
	momentPo, err := momentRepo.GetMoment(ctx, repo.GetMomentRequest{
		MomentID: req.MomentID,
	})
	if err != nil {
		return nil, err
	}
	momentEntity, err := NewMomentEntityByPo(ctx, momentPo)
	if err != nil {
		return nil, err
	}
	return momentEntity, nil
}

func NewMomentEntityByPo(ctx context.Context, momentPo *po.Moment) (*Moment, error) {
	momentEntity := &Moment{
		ID:       momentPo.ID,
		MomentID: momentPo.MomentID,
		User: User{
			UserID: momentPo.UserID,
		},
		ViewCount:    momentPo.ViewCount,
		CommentCount: momentPo.CommentCount,
		LikeCount:    momentPo.LikeCount,
		CreateAt:     momentPo.CreatedAt,
	}
	err := json.Unmarshal(momentPo.Content, &momentEntity.Content)
	if err != nil {
		return nil, err
	}
	return momentEntity, nil
}

func (m *Moment) SetMomentID() error {
	m.MomentID = config.GenerateIDInt64()
	return nil
}

func (m *Moment) Persist(ctx context.Context) error {
	momentRepo := repo.NewMomentRepo(ctx)
	momentPo, err := momentRepo.CreateMoment(ctx, m.ToPo(ctx))
	if err != nil {
		return err
	}
	// 创建时间以存入数据库的时间为准(momentRepo.CreateMoment会修改m对象的创建时间)
	m.CreateAt = momentPo.CreatedAt
	return nil
}

func (m *Moment) ToPo(ctx context.Context) *po.Moment {
	j, _ := json.Marshal(m.Content)
	return &po.Moment{
		ID:           m.ID,
		MomentID:     m.MomentID,
		UserID:       m.User.UserID,
		Content:      j,
		ViewCount:    m.ViewCount,
		CommentCount: m.CommentCount,
		LikeCount:    m.LikeCount,
	}
}

func (m *Moment) ToVo() vo.Moment {
	return vo.Moment{
		MomentID: cast.ToString(m.MomentID),
		UserID:   cast.ToString(m.User.UserID),
		HeadURL:  m.User.HeadURL,
		Nickname: m.User.Nickname,
		Content: vo.PostContent{
			Text:      m.Content.Text,
			ImageURLs: m.Content.ImageUrls,
		},
		ViewCount:    m.ViewCntDesc(),
		CommentCount: m.CommentCount,
		LikeCount:    m.LikeCount,
		ILikeIt:      m.ILikeIt,
		CreateAt:     util.ToTimeString(m.CreateAt),
	}
}

// ViewCntDesc 浏览量文案描述
func (m *Moment) ViewCntDesc() string {
	return cast.ToString(m.ViewCount)
}
